﻿#include "../../ctlCheckBox.h"
#include "../../ctlRadioBox.h"
#include "../../ctlHelp.h"

namespace swui
{
	bool ctlSelectableBox::setText(const ctlText& lpszText) {
		lockDrawing();
		bool result = ctlRoot::setText(lpszText);
		unlockDrawing();
		if(result) _flush_rect_();
		return result;
	}
	bool ctlSelectableBox::isSelected() {
		return _selected;
	}
	void ctlSelectableBox::_flush_font_()
	{
//		if(isFontFlushRedrawLocked()) return;
		lockDrawing();
		IFont::_flush_font_();
		unlockDrawing();
		_flush_rect_();
	}
	void ctlSelectableBox::_flush_rect_() {
		ctlPoint rsize = _getTextSize();
		size(ctlSelectableBox::BoxWidth + ctlSelectableBox::TextOffset + rsize.x, 
			ctlMax(ctlSelectableBox::BoxWidth, rsize.y));
	}
	ctlRect ctlSelectableBox::_getBoxRect() {
		return ctlRect(getLeft(), getTop() + (getHeight() - ctlSelectableBox::BoxWidth) / 2, 
			ctlSelectableBox::BoxWidth, ctlSelectableBox::BoxWidth);
	}
	
	void ctlCheckBox::setSelect(bool isSelect) {
		ctlNotifyEvent ne;
		ne.eventType = ctlNotifyEventType::selectChange;
		ne.info = nullptr;
		_selected = isSelect;
		_notify_event_(&ne);
		redraw();
	}
	bool ctlCheckBox::create(ctlRoot* parent, ctlPoint point, const ctlText& lpszText, const ctlStyleBase& style)
	{
		if(parent == 0 || isCreated() || !parent->isCreated()) return false; 
		std::lock_guard<decltype(_eventTrans)> gurad(
			_eventTrans.getControlEventTrans(parent));
		_control_virtual_class_end = this;
		_basic_create_(ctlRect(point.x, point.y, 0, 0), parent);
		_controlType = ctlControlType::ctlCheckBox;
		_virtual_font_create();
		lockDrawing();
		setSelect(false);
		setStyle(style);
		setText(lpszText);
		unlockDrawing();
		redraw();
		return true;
	}

	
	inline void _ctlInterior::_ctlRadioSelector::pop(unsigned group, ctlRadioBox* node)
	{
		auto& gp = data[group];
		for(auto begin = gp.list.begin(), 
			end = gp.list.end(); begin != end; ++begin)
		{
			if(*begin == node)
			{
				if(gp.selected == *begin)
					gp.selected = nullptr;
				gp.list.erase(begin);
				break;
			}
		}
	}
	bool _ctlInterior::_ctlRadioSelector::select(unsigned group, ctlRadioBox* node)
	{
		auto& selected = data[group].selected;
		if(selected == node) return false;
		if(selected)
		{
			selected->_selected = false;
			ctlNotifyEvent ne;
			ne.info = nullptr;
			ne.eventType = ctlNotifyEventType::selectChange;
			selected->_notify_event_(&ne);
		}
		selected = node;
		return true;
	}


	inline unsigned ctlRadioBox::getGroup() { return _radio_group; }
	bool ctlRadioBox::create(ctlRoot* parent, ctlPoint point, 
		unsigned group, const ctlText& lpszText, const ctlStyleBase& style)
	{
		if(parent == 0 || isCreated() || !parent->isCreated()) return false;
		std::lock_guard<decltype(_eventTrans)> gurad(
			_eventTrans.getControlEventTrans(parent)); 
		_control_virtual_class_end = this;
		_basic_create_(ctlRect(point.x, point.y, 0, 0), parent);
		_controlType = ctlControlType::ctlRadioBox;
		_virtual_font_create();
		lockDrawing();
		_selected = false;
		_radio_group = group;
		_eventTrans.getMajorInfo()->radioGroup.push(group, this);
		setStyle(style);
		setText(lpszText);
		unlockDrawing();
		redraw();
		return true;
	}
	void ctlRadioBox::setSelect()
	{
		if(_eventTrans.getMajorInfo()->radioGroup.select(getGroup(), this))
		{
			_selected = true;
			ctlNotifyEvent ne;
			ne.info = nullptr;
			ne.eventType = ctlNotifyEventType::selectChange;
			_notify_event_(&ne);
			redrawAllControl();
		}
	}
	void ctlRadioBox::destroy()
	{
		if(isCreated())
			_eventTrans.getMajorInfo()->radioGroup.pop(getGroup(), this);
		ctlSelectableBox::destroy();
	}
	unsigned ctlRadioBox::allocNewGroup()
	{ 
		return _eventTrans.getMajorInfo()->radioGroup.allow();
	}

	void ctlRadioBox::_mouse_event_(ctlMouseEvent* info) {
		if(info->eventModel != ctlMouseEventModel::cut) return;
		if(info->eventType == ctlMouseEventType::leftPress)
			setSelect();
		ctlRoot::_mouse_event_(info);
		ISmoothTransform::_smooth_transform_mouse_event(info);
	}
	void ctlCheckBox::_mouse_event_(ctlMouseEvent* info) {
		if(info->eventModel != ctlMouseEventModel::cut) return;
		if(info->eventType == ctlMouseEventType::leftPress)
			setSelect(!isSelected());
		ctlRoot::_mouse_event_(info);
		ISmoothTransform::_smooth_transform_mouse_event(info);
	}
}